home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-03 | 33.9 KB | 1,418 lines |
- Newsgroups: comp.sources.unix
- From: rogers@amadeus.wr.tek.com (Roger S. Southwick)
- Subject: v25i093: hostcvt - convert /etc/hosts files into DNS zone files
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: rogers@amadeus.wr.tek.com (Roger S. Southwick)
- Posting-Number: Volume 25, Issue 93
- Archive-Name: hostcvt
-
- Here is a couple of programs for converting /etc/hosts files
- into files useful for the BIND Nameserver.
-
- Roger S. Southwick
- rogers@amadeus.wr.tek.com
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: Makefile README egetopt.c gethostent.c hostcvt.8 main.c
- # nextserial.8 nextserial.c
- # Wrapped by rogers@fangorn on Mon Nov 25 18:08:11 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(972 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- X#
- X# Makefile for hostcvt and nextserial
- X#
- X# $Id: Makefile,v 1.4 91/11/25 17:44:43 rogers Release $
- X#
- X
- XBINDIR = /etc/named_data/bin
- XMANDIR = /usr/manl/man8
- X
- XCFLAGS = -O
- XLDFLAGS = -s
- X
- Xall : hostcvt nextserial
- X
- Xhostcvt : main.o gethostent.o egetopt.o
- X cc $(LDFLAGS) -o hostcvt main.o gethostent.o egetopt.o
- X
- Xnextserial : nextserial.c
- X cc $(CFLAGS) $(LDFLAGS) -o nextserial nextserial.c
- X
- Xegetopt : egetopt.c
- X cc $(CFLAGS) $(LDFLAGS) -c egetopt.c
- X
- X
- Xinstall : $(BINDIR)/hostcvt $(BINDIR)/nextserial \
- X $(MANDIR)/hostcvt.8 $(MANDIR)/nextserial.8
- X
- X$(BINDIR)/hostcvt : hostcvt
- X install -c -m 0755 hostcvt $(BINDIR)
- X
- X$(BINDIR)/nextserial : nextserial
- X install -c -m 0755 nextserial $(BINDIR)
- X
- X$(MANDIR)/hostcvt.8 : hostcvt.8
- X install -c -m 0644 hostcvt.8 $(MANDIR)
- X
- X$(MANDIR)/nextserial.8 : nextserial.8
- X install -c -m 0644 nextserial.8 $(MANDIR)
- X
- Xlint : main.c gethostent.c nextserial.c
- X lint main.c gethostent.c
- X lint nextserial.c
- X
- Xclean :
- X rm -f hostcvt nextserial *.o make.out
- X
- END_OF_Makefile
- if test 972 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(498 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- XPrograms to convert /etc/hosts files into BIND files.
- X
- XNo warrenty written or implied. You are free to use this program
- Xas long as you don't make money with it. If you find bugs or
- Xmake enhancements, please send me a patch file.
- X
- XMany thanks to Mark Frost (mfrost@pyramid.com) who modified
- Xthe code to handle multiple domains and different files.
- X
- X -Roger (rogers@amadeus.wr.tek.com)
- X UUCP: ...!uunet!tektronix!amadeus.wr.tek.com!rogers
- X ARPA: <@RELAY.CS.NET:rogers@amadeus.wr.tek.com>
- END_OF_README
- if test 498 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f egetopt.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"egetopt.c\"
- else
- echo shar: Extracting \"egetopt.c\" \(6954 characters\)
- sed "s/^X//" >egetopt.c <<'END_OF_egetopt.c'
- X/*
- X * egetopt.c -- Extended 'getopt'.
- X *
- X * A while back, a public-domain version of getopt() was posted to the
- X * net. A bit later, a gentleman by the name of Keith Bostic made some
- X * enhancements and reposted it.
- X *
- X * In recent weeks (i.e., early-to-mid 1988) there's been some
- X * heated discussion in comp.lang.c about the merits and drawbacks
- X * of getopt(), especially with regard to its handling of '?'.
- X *
- X * In light of this, I have taken Mr. Bostic's public-domain getopt()
- X * and have made some changes that I hope will be considered to be
- X * improvements. I call this routine 'egetopt' ("Extended getopt").
- X * The default behavior of this routine is the same as that of getopt(),
- X * but it has some optional features that make it more useful. These
- X * options are controlled by the settings of some global variables.
- X * By not setting any of these extra global variables, you will have
- X * the same functionality as getopt(), which should satisfy those
- X * purists who believe getopt() is perfect and can never be improved.
- X * If, on the other hand, you are someone who isn't satisfied with the
- X * status quo, egetopt() may very well give you the added capabilities
- X * you want.
- X *
- X * Look at the enclosed README file for a description of egetopt()'s
- X * new features.
- X *
- X * The code was originally posted to the net as getopt.c by ...
- X *
- X * Keith Bostic
- X * ARPA: keith@seismo
- X * UUCP: seismo!keith
- X *
- X * Current version: added enhancements and comments, reformatted code.
- X *
- X * Lloyd Zusman
- X * Master Byte Software
- X * Los Gatos, California
- X * Internet: ljz@fx.com
- X * UUCP: ...!ames!fxgrp!ljz
- X *
- X * May, 1988
- X */
- X
- X#ifndef lint
- Xstatic char *RCSid = "$Id: egetopt.c,v 1.1 91/11/25 17:45:07 rogers Release $";
- X#endif
- X
- X/*
- X * If you want, include stdio.h or something where EOF and NULL are defined.
- X * However, egetopt() is written so as not to need stdio.h, which should
- X * make it significantly smaller on some systems.
- X */
- X
- X#ifndef EOF
- X# define EOF (-1)
- X#endif /* ! EOF */
- X
- X#ifndef NULL
- X# define NULL (char *)0
- X#endif /* ! NULL */
- X
- X/*
- X * None of these constants are referenced in the executable portion of
- X * the code ... their sole purpose is to initialize global variables.
- X */
- X#define BADCH (int)'?'
- X#define NEEDSEP (int)':'
- X#define MAYBESEP (int)'\0'
- X#define ERRFD 2
- X#define EMSG ""
- X#define START "-"
- X
- X/*
- X * Here are all the pertinent global variables.
- X */
- Xint opterr = 1; /* if true, output error message */
- Xint optind = 1; /* index into parent argv vector */
- Xint optopt; /* character checked for validity */
- Xint optbad = BADCH; /* character returned on error */
- Xint optchar = 0; /* character that begins returned option */
- Xint optneed = NEEDSEP; /* flag for mandatory argument */
- Xint optmaybe = MAYBESEP;/* flag for optional argument */
- Xint opterrfd = ERRFD; /* file descriptor for error text */
- Xchar *optarg; /* argument associated with option */
- Xchar *optstart = START; /* list of characters that start options */
- X
- X
- X/*
- X * Macros.
- X */
- X
- X/*
- X * Conditionally print out an error message and return (depends on the
- X * setting of 'opterr' and 'opterrfd'). Note that this version of
- X * TELL() doesn't require the existence of stdio.h.
- X */
- X#define TELL(S) { \
- X if (opterr && opterrfd >= 0) { \
- X char option = optopt; \
- X (void)write(opterrfd, *nargv, strlen(*nargv)); \
- X (void)write(opterrfd, (S), strlen(S)); \
- X (void)write(opterrfd, &option, 1); \
- X (void)write(opterrfd, "\n", 1); \
- X } \
- X return (optbad); \
- X}
- X
- X/*
- X * This works similarly to index() and strchr(). I include it so that you
- X * don't need to be concerned as to which one your system has.
- X */
- Xstatic char *
- X_sindex(string, ch)
- Xchar *string;
- Xint ch;
- X{
- X if (string != NULL) {
- X for (; *string != '\0'; ++string) {
- X if (*string == (char)ch) {
- X return (string);
- X }
- X }
- X }
- X
- X return (NULL);
- X}
- X
- X/*
- X * Here it is:
- X */
- Xint
- Xegetopt(nargc, nargv, ostr)
- Xint nargc;
- Xchar **nargv;
- Xchar *ostr;
- X{
- X static char *place = EMSG; /* option letter processing */
- X register char *oli; /* option letter list index */
- X register char *osi = NULL; /* option start list index */
- X
- X if (nargv == (char **)NULL) {
- X return (EOF);
- X }
- X
- X if (nargc <= optind || nargv[optind] == NULL) {
- X return (EOF);
- X }
- X
- X if (place == NULL) {
- X place = EMSG;
- X }
- X
- X /*
- X * Update scanning pointer.
- X */
- X if (*place == '\0') {
- X place = nargv[optind];
- X if (place == NULL) {
- X return (EOF);
- X }
- X osi = _sindex(optstart, *place);
- X if (osi != NULL) {
- X optchar = (int)*osi;
- X }
- X if (optind >= nargc || osi == NULL || *++place == '\0') {
- X return (EOF);
- X }
- X
- X /*
- X * Two adjacent, identical flag characters were found.
- X * This takes care of "--", for example.
- X */
- X if (*place == place[-1]) {
- X ++optind;
- X return (EOF);
- X }
- X }
- X
- X /*
- X * If the option is a separator or the option isn't in the list,
- X * we've got an error.
- X */
- X optopt = (int)*place++;
- X oli = _sindex(ostr, optopt);
- X if (optopt == optneed || optopt == optmaybe || oli == NULL) {
- X /*
- X * If we're at the end of the current argument, bump the
- X * argument index.
- X */
- X if (*place == '\0') {
- X ++optind;
- X }
- X TELL(": illegal option -- "); /* byebye */
- X }
- X
- X /*
- X * If there is no argument indicator, then we don't even try to
- X * return an argument.
- X */
- X ++oli;
- X if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
- X /*
- X * If we're at the end of the current argument, bump the
- X * argument index.
- X */
- X if (*place == '\0') {
- X ++optind;
- X }
- X optarg = NULL;
- X }
- X /*
- X * If we're here, there's an argument indicator. It's handled
- X * differently depending on whether it's a mandatory or an
- X * optional argument.
- X */
- X else {
- X /*
- X * If there's no white space, use the rest of the
- X * string as the argument. In this case, it doesn't
- X * matter if the argument is mandatory or optional.
- X */
- X if (*place != '\0') {
- X optarg = place;
- X }
- X /*
- X * If we're here, there's whitespace after the option.
- X *
- X * Is it a mandatory argument? If so, return the
- X * next command-line argument if there is one.
- X */
- X else if (*oli == optneed) {
- X /*
- X * If we're at the end of the argument list, there
- X * isn't an argument and hence we have an error.
- X * Otherwise, make 'optarg' point to the argument.
- X */
- X if (nargc <= ++optind) {
- X place = EMSG;
- X TELL(": option requires an argument -- ");
- X }
- X else {
- X optarg = nargv[optind];
- X }
- X }
- X /*
- X * If we're here it must have been an optional argument.
- X */
- X else {
- X if (nargc <= ++optind) {
- X place = EMSG;
- X optarg = NULL;
- X }
- X else {
- X optarg = nargv[optind];
- X if (optarg == NULL) {
- X place = EMSG;
- X }
- X /*
- X * If the next item begins with a flag
- X * character, we treat it like a new
- X * argument. This is accomplished by
- X * decrementing 'optind' and returning
- X * a null argument.
- X */
- X else if (_sindex(optstart, *optarg) != NULL) {
- X --optind;
- X optarg = NULL;
- X }
- X }
- X }
- X place = EMSG;
- X ++optind;
- X }
- X
- X /*
- X * Return option letter.
- X */
- X return (optopt);
- X}
- END_OF_egetopt.c
- if test 6954 -ne `wc -c <egetopt.c`; then
- echo shar: \"egetopt.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f gethostent.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"gethostent.c\"
- else
- echo shar: Extracting \"gethostent.c\" \(2771 characters\)
- sed "s/^X//" >gethostent.c <<'END_OF_gethostent.c'
- X/*
- X * Copyright (c) 1983 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netdb.h>
- X#include <ctype.h>
- X
- X#ifndef lint
- Xstatic char *RCSid = "$Id: gethostent.c,v 1.2 90/10/03 22:50:29 rogers Release $";
- X#endif
- X
- X/*
- X * Internet version.
- X */
- X#define MAXALIASES 35
- X#define MAXADDRSIZE 14
- X
- Xstatic FILE *hostf = NULL;
- Xstatic char line[BUFSIZ+1];
- Xstatic char hostaddr[MAXADDRSIZE];
- Xstatic struct hostent host;
- Xstatic char *host_aliases[MAXALIASES];
- Xstatic char *host_addrs[] = {
- X hostaddr,
- X NULL
- X};
- X
- X/*
- X * The following is shared with gethostnamadr.c
- X */
- X
- Xstatic char *any();
- X
- X#ifdef NOTUSEDINHOSTCVT
- X
- Xmysethostent()
- X{
- X if (hostf != NULL)
- X rewind(hostf);
- X}
- X
- Xmyendhostent()
- X{
- X if (hostf != NULL) {
- X (void)fclose(hostf);
- X hostf = NULL;
- X }
- X}
- X#endif /* NOTUSEDINHOSTCVT */
- X
- Xstruct hostent *
- Xmygethostent(fname)
- Xchar *fname;
- X{
- X u_long inet_addr();
- X char *p;
- X register char *cp, **q;
- X
- X if (hostf == NULL && (hostf = fopen(fname, "r" )) == NULL)
- X return (NULL);
- Xagain:
- X if ((p = fgets(line, BUFSIZ, hostf)) == NULL)
- X return (NULL);
- X if (*p == '#')
- X goto again;
- X cp = any(p, "#\n");
- X if (cp == NULL)
- X goto again;
- X *cp = '\0';
- X cp = any(p, " \t");
- X if (cp == NULL)
- X goto again;
- X *cp++ = '\0';
- X /* THIS STUFF IS INTERNET SPECIFIC */
- X host.h_addr_list = host_addrs;
- X *((u_long *)host.h_addr) = inet_addr(p);
- X host.h_length = sizeof (u_long);
- X host.h_addrtype = AF_INET;
- X while (*cp == ' ' || *cp == '\t')
- X cp++;
- X host.h_name = cp;
- X q = host.h_aliases = host_aliases;
- X cp = any(cp, " \t");
- X if (cp != NULL)
- X *cp++ = '\0';
- X while (cp && *cp) {
- X if (*cp == ' ' || *cp == '\t') {
- X cp++;
- X continue;
- X }
- X if (q < &host_aliases[MAXALIASES - 1])
- X *q++ = cp;
- X cp = any(cp, " \t");
- X if (cp != NULL)
- X *cp++ = '\0';
- X }
- X *q = NULL;
- X return (&host);
- X}
- X
- Xstatic char *
- Xany(cp, match)
- X register char *cp;
- X char *match;
- X{
- X register char *mp, c;
- X
- X while (c = *cp) {
- X for (mp = match; *mp; mp++)
- X if (*mp == c)
- X return (cp);
- X cp++;
- X }
- X return ((char *)0);
- X}
- END_OF_gethostent.c
- if test 2771 -ne `wc -c <gethostent.c`; then
- echo shar: \"gethostent.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f hostcvt.8 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"hostcvt.8\"
- else
- echo shar: Extracting \"hostcvt.8\" \(4360 characters\)
- sed "s/^X//" >hostcvt.8 <<'END_OF_hostcvt.8'
- X.\"
- X.\" $Id: hostcvt.8,v 1.2 91/11/25 17:45:24 rogers Release $
- X.\"
- X.TH HOSTCVT 8 "10-3-90"
- X.SH NAME
- Xhostcvt - Convert hosts(5) file to BIND files
- X.SH SYNOPSIS
- X.B hostcvt
- X[ -s
- X.I soabasefile
- X] [ -n
- X.I netfile
- X]
- X[ -h
- X.I hostfile
- X]
- X.br
- X [ -o
- X.I outputfile
- X] domain
- X.SH DESCRIPTION
- X.LP
- X.I hostcvt
- Xreads a hosts(5) file specified by the
- X.I hostfile
- Xargument ("hosts.thisdomain" by default), and converts them to
- XBIND hostname-to-address and reverse tables for the argument
- X.I
- Xdomain.
- XThe names of the reverse files are specified in the argument
- X.I netfile
- X("netlist" by default).
- XIf no output file is specified, the hostname to address table is put
- Xinto a file in the current directory named
- X.I domain.
- XAll files are prepended with the
- X.I soabasefile
- X("soabasefile" by default) which is the SOA record for this domain (see example
- Xbelow).
- X.LP
- X.B Hostcvt
- Xissues warnings for any duplicated names (name to name, name to
- Xaliases, aliases to name and aliases to aliases) and will only allow
- Xthe first instance of a name from
- X.I hostsfile
- Xto be in the outputfile and the reverse table files. Lines in
- X.I hostsfile
- Xthat have an IP address but no hostname are ignored and a warning message is
- Xprinted.
- X.LP
- X.SH OPTIONS
- X.TP
- X.BI \-h " hostsfile"
- XSpecify a file in hosts(5) format to read hosts from. The default is
- X"hosts.thisdomain".
- X.TP
- X.BI \-n " netfile"
- XSpecify a
- X.I netfile.
- XThis file specifies the names of the reverse tables. The default is "netlist".
- X.LP
- X.TP
- X.BI \-o " outputfile"
- XSpecify an output file for the hostname-to-address file. If unspecified, this
- Xfile is the same as
- X.I domainname.
- X.LP
- X.TP
- X.BI \-s " soabasefile"
- XSpecify an SOA file. The default is "soabasefile".
- X.SH "FORMAT OF THE NETLIST FILE"
- X.LP
- X.I netfile
- Xhas the format:
- X.RS
- X.nf
- X
- Xnetportion file
- X.fi
- X.RE
- X.LP
- XThe
- X.I netportion
- Xdescribes the portion of the address field which hostcvt is to pay attention
- Xto. The
- X.I netportion
- Xshould be all digits and dots necessary to do a strncmp() against the
- Xaddress portion of
- X.I hostsfile,
- Xtaking into account how the
- X.I named.boot
- Xfile is set up for the reverse address translation.
- X.LP
- XThe
- X.I file
- Xis the path to the file the reverse address for this
- X.I netportion.
- X.LP
- XFor example, suppose named.boot file has the following reverse translations:
- X.RS
- X.nf
- X
- Xprimary 36.in-addr.arpa net/net36
- Xprimary 0.101.in-addr.arpa net/net101
- Xprimary 0.0.100.in-addr.arpa net/net127
- Xprimary 63.134.in-addr.arpa reversefile
- X.fi
- X.RE
- X.LP
- XFor the net 36 addresses, the
- X.I hostsfile
- Xwould have entries of 36.xx.yy.zz, where all three lower portions
- Xwould be used. For the net 101 addresses, the
- X.I hosts.thisdomain
- Xfile would have 101.0.yy.zz entries. And so forth.
- X.LP
- XThe corresponding
- X.I netfile
- Xwould show:
- X.RS
- X.nf
- X
- X36. net/net36
- X101.0. net/net101
- X100.0.0. net/net100
- X134.63. reversefile
- X.fi
- X.RE
- X.LP
- XIt is VERY important that the trailing dot be in the
- X.I netportion
- Xof the
- X.I netfile.
- XThe program does a strncmp() against the host address field of
- X.I hostsfile
- Xusing the
- X.I netportion
- Xstring and it's length to get the exact match (O.K., so the program is
- Xa hack).
- X.LP
- X.B Hostcvt
- Xignores lines starting with a # (pound sign) or empty (i.e. ^$ in egrep terms)
- Xlines in the
- X.I netlist
- Xfile. These may be used for comments or separation.
- X.SH "FORMAT OF THE SOABASEFILE"
- X.LP
- XThe
- X.I soabasefile
- Xis the SOA record which is prepended to all output files, and should
- Xbe a valid SOA format. Here is the
- X.I soabasefile
- Xfor our domain (wr.tek.com):
- X.RS
- X.nf
- X
- X@ IN SOA wrgate.wr.tek.com. wrap.wrgate.wr.tek.com. (
- X 1 ; Serial
- X 3600 ; Refresh
- X 300 ; Retry
- X 3600000 ; Expire
- X 14400 ) ; Minimum
- X IN NS wrgate.wr.tek.com.
- X.fi
- X.RE
- X.LP
- XNote that the Serial number in the
- X.I soabasefile
- Xshould be advanced before
- X.B hostcvt
- Xis run, rather than trying to change all the SOA records in the resulting
- Xfiles. The
- X.B nextserial
- Xprogram is a convenient tool for changing the Serial numbers in files.
- X.SH "EXAMPLE USAGE"
- X.LP
- XThe following is what I do to convert my
- X.I hostsfile
- Xinto files for my domain:
- X.RS
- X.nf
- Xnextserial soabasefile
- Xhostcvt -s soabasefile wr.tek.com
- X.fi
- X.RE
- X.SH "SEE ALSO"
- Xhosts(5), nextserial(8)
- X.SH BUGS
- XIt would also be nice to retain comments made in
- X.I hostsfile.
- X.LP
- X.SH AUTHOR
- XRoger S. Southwick
- X.br
- Xrogers@amadeus.wr.tek.com
- X.LP
- XModifications by Mark Frost
- X.br
- Xmfrost@pyramid.com
- END_OF_hostcvt.8
- if test 4360 -ne `wc -c <hostcvt.8`; then
- echo shar: \"hostcvt.8\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main.c\"
- else
- echo shar: Extracting \"main.c\" \(10143 characters\)
- sed "s/^X//" >main.c <<'END_OF_main.c'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <arpa/inet.h>
- X#include <netdb.h>
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X
- X#ifndef lint
- Xstatic char *RCSid = "$Id: main.c,v 1.4 91/11/25 17:46:06 rogers Release $";
- X
- X#endif
- X
- Xstruct netlist {
- X char *nl_net; /* Net number portion */
- X int nl_netlen; /* Length of above */
- X char *nl_file; /* File name */
- X FILE *nl_fp; /* Pointer to above */
- X struct netlist *nl_next; /* Next one */
- X};
- X
- Xtypedef struct netlist nl_t;
- Xtypedef struct netlist *nl_tp;
- X
- Xstruct host_names {
- X char *h_name;
- X char **h_aliases;
- X struct host_names *h_next;
- X};
- X
- Xtypedef struct host_names hn_t;
- Xtypedef struct host_names *hn_tp;
- X
- Xchar *soa = NULL; /* The soa from argv[] */
- Xchar *domain = NULL; /* Domain name from argv[] */
- Xnl_tp ntop = NULL; /* Top of linked list */
- Xhn_tp hntop = NULL; /* Top of list of hostnames */
- Xchar *hostsfile, *netfile, *soafile, *outputfile;
- Xextern char *optarg; /* for egetopt() */
- X
- Xextern int optind; /* for egetopt() */
- Xextern int errno;
- Xextern char *sys_errlist[];
- X
- X#define ERR sys_errlist[errno], errno
- X
- Xvoid exit();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *fopen();
- X char *strsave(), *malloc();
- X struct hostent *mygethostent();
- X register struct hostent *hp;
- X register FILE *fp;
- X register char *ipaddr, **cpp;
- X register nl_tp np;
- X struct in_addr foo;
- X
- X char ch;
- X int hostflag, soaflag, netflag, errflag, outputflag, domainflag;
- X
- X hostflag = soaflag = netflag = errflag = outputflag = domainflag = 0;
- X hostsfile = soafile = netfile = domain = outputfile = NULL;
- X
- X
- X while ((ch = egetopt(argc, argv, "h:n:o:s:")) != -1)
- X switch (ch) {
- X case 'h': /* assign name for "hosts" file (sourcefile) */
- X if (hostflag){
- X errflag++;
- X }
- X else {
- X hostsfile = strsave(optarg);
- X hostflag++;
- X }
- X break;
- X
- X case 'n': /* assign name for "netlist" */
- X if (netflag){
- X errflag++;
- X }
- X else {
- X netfile = strsave(optarg);
- X netflag++;
- X }
- X break;
- X
- X case 'o': /* assign name for main output file */
- X if (outputflag){
- X errflag++;
- X }
- X else {
- X outputfile = strsave(optarg);
- X outputflag++;
- X }
- X break;
- X
- X case 's': /* assign name for "soabasefile" */
- X if (soaflag){
- X errflag++;
- X }
- X else {
- X soafile = strsave(optarg);
- X soaflag++;
- X }
- X break;
- X
- X case '?': /* anything else that might show up */
- X errflag++;
- X
- X } /* switch */
- X
- X for (; optind < argc; optind++) {
- X if (domainflag) {
- X errflag++;
- X break;
- X } /* if */
- X else {
- X domain = strsave(argv[optind]);
- X domainflag++;
- X } /* else */
- X } /* for */
- X
- X if (errflag || domain == NULL || (strlen(domain) < 2)) {
- X (void) fprintf(stderr, "usage: hostcvt [-h hostsfile] [-n netlistfile]\n\t\t[-s soabasefile] [-o outputfile] domain\n");
- X exit(2);
- X }
- X
- X if (!netflag){
- X netfile = strsave("netlist");
- X }
- X
- X if (!hostflag){
- X hostsfile = strsave("hosts.thisdomain");
- X }
- X
- X if (!soafile) {
- X soafile = strsave("soabasefile");
- X }
- X if (!outputflag){
- X outputfile = domain;
- X }
- X
- X rdsoa(soafile);
- X
- X (void)close(0);
- X (void)close(1);
- X
- X if((fp = fopen(outputfile, "w")) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not open %s\n", outputfile);
- X exit(1);
- X }
- X
- X if(access(hostsfile, R_OK) == -1) {
- X (void) fprintf(stderr, "hostcvt: no host file %s\n", hostsfile);
- X exit(1);
- X }
- X
- X if(soa != NULL) {
- X (void) fputs(soa, fp);
- X }
- X
- X rdnetlist();
- X
- X while ((hp = mygethostent(hostsfile)) != NULL) {
- X foo.s_addr = (u_long) * ((u_long *) hp->h_addr);
- X ipaddr = inet_ntoa(foo);
- X if (outnet(ipaddr, hp->h_name)) {
- X
- X if (isdup(hp)){
- X continue;
- X }
- X
- X if (strlen(hp->h_name) == 0) {
- X (void)fprintf(stderr, "No name found for %s -- ignoring...\n", ipaddr);
- X }
- X else {
- X savehp(hp);
- X
- X (void) fprintf(fp, "%s\t\tIN\tA\t%s\n", hp->h_name, ipaddr);
- X
- X for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
- X if (strcasecmp(*cpp, hp->h_name) != 0) {
- X (void) fprintf(fp, "%s\t\tIN\tCNAME\t%s\n", *cpp, hp->h_name);
- X }
- X } /* else */
- X }
- X }
- X }
- X (void) fflush(fp);
- X (void) fclose(fp);
- X for (np = ntop; np != NULL; np = np->nl_next) {
- X (void) fflush(np->nl_fp);
- X (void) fclose(np->nl_fp);
- X }
- X
- X return(0);
- X}
- X
- X/*
- X * See if the new hostname or any of it's aliases
- X * are already known.
- X */
- X
- Xint
- Xisdup(hp)
- Xregister struct hostent *hp;
- X{
- X register hn_tp np;
- X register char **cpp, **acp;
- X
- X /*
- X * For each node in our linked list of known names....
- X */
- X
- X for (np = hntop; np != NULL; np = np->h_next) {
- X
- X /*
- X * See if the new name matches directly
- X */
- X
- X if (strcasecmp(hp->h_name, np->h_name) == 0) {
- X (void) fprintf(stderr, "hostcvt: duplicated name: %s\n", hp->h_name);
- X return (1);
- X }
- X
- X /*
- X * See if the new name matches an alias
- X */
- X
- X for (acp = np->h_aliases; *acp != NULL; acp++) {
- X if (strcasecmp(hp->h_name, *acp) == 0) {
- X (void) fprintf(stderr, "hostcvt: duplicated name to alias: %s\n", hp->h_name);
- X return (1);
- X }
- X }
- X
- X /*
- X * For each of the new machines aliases
- X */
- X
- X for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
- X
- X /*
- X * See if the alias matches the real name
- X */
- X
- X if (strcasecmp(*cpp, np->h_name) == 0) {
- X (void) fprintf(stderr, "hostcvt: duplicated alias to name: %s\n", hp->h_name);
- X return (1);
- X }
- X
- X /*
- X * See if the alias matches one of our aliases
- X */
- X
- X for (acp = np->h_aliases; *acp != NULL; acp++) {
- X if (strcasecmp(*acp, *cpp) == 0) {
- X (void) fprintf(stderr, "hostcvt: duplicated alias to alias: %s\n", hp->h_name);
- X return (1);
- X }
- X }
- X }
- X }
- X
- X return (0); /* No match */
- X}
- X
- Xsavehp(hp)
- Xregister struct hostent *hp;
- X{
- X char *malloc(), *strsave();
- X register char **cpp, **acp;
- X register int cnt;
- X register hn_tp np;
- X
- X if ((np = (hn_tp) malloc(sizeof(hn_t))) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
- X exit(1);
- X }
- X
- X np->h_name = strsave(hp->h_name);
- X
- X for (cnt = 1, cpp = hp->h_aliases; *cpp != NULL; cpp++)
- X cnt++;
- X
- X if ((np->h_aliases = (char **) malloc((unsigned) (cnt * sizeof(char **)))) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
- X exit(1);
- X }
- X
- X for (cpp = hp->h_aliases, acp = np->h_aliases; *cpp != NULL; cpp++, acp++) {
- X *acp = strsave(*cpp);
- X }
- X *acp = NULL;
- X
- X np->h_next = hntop;
- X hntop = np;
- X}
- X
- X/*
- X * Add the host named "name" at the IP address "ip" to
- X * the proper net file. Return 1 if done OK, 0 if not.
- X */
- X
- Xint
- Xoutnet(ip, name)
- Xchar *ip, *name;
- X{
- X char *strcpy(), *index(), *strsave();
- X register nl_tp np;
- X register int i;
- X register char *last, *cp, *ipaddr;
- X char dig[4][20];
- X
- X ipaddr = strsave(ip);
- X
- X for (np = ntop; np != NULL; np = np->nl_next) {
- X if (strncmp(ipaddr, np->nl_net, np->nl_netlen) == 0) {
- X last = ipaddr + np->nl_netlen;
- X bzero((char *) dig, sizeof(dig));
- X
- X for (i = 0; *last != '\0'; i++) {
- X if ((cp = index(last, '.')) == NULL){
- X break;
- X }
- X
- X *cp = '\0';
- X (void) strcpy(dig[i], last);
- X last = cp + 1;
- X }
- X
- X (void) fprintf(np->nl_fp, "%s", last);
- X
- X for (i = 3; i >= 0; i--) {
- X if (dig[i][0] != '\0'){
- X (void) fprintf(np->nl_fp, ".%s", dig[i]);
- X }
- X }
- X (void) fprintf(np->nl_fp, "\t\tIN\tPTR\t%s.%s.\n", name, domain);
- X return (1);
- X }
- X }
- X (void) fprintf(stderr, "hostcvt: could not find file for %s (add= %s)\n", name, ipaddr);
- X return (0);
- X}
- X
- Xrdnetlist()
- X{
- X char *strsave(), *malloc(), *index();
- X FILE *fopen();
- X register FILE *fp;
- X register nl_tp np;
- X register int i, cnt;
- X char nbuf[256], fbuf[512], buf[BUFSIZ];
- X
- X if ((fp = fopen(netfile, "r")) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not open %s\n", netfile);
- X exit(1);
- X }
- X
- X for (i = 1, cnt = 0; fgets(buf, BUFSIZ, fp) != NULL; i++) {
- X if (buf[0] == '#' || buf[0] == '\n'){ /* allow comments and blanks */
- X continue;
- X }
- X
- X if (sscanf(buf, "%s %s", nbuf, fbuf) != 2) {
- X (void) fprintf(stderr, "hostcvt: error on line #%d in %s, contents= %s", i, netfile, buf);
- X continue;
- X }
- X
- X if ((np = (nl_tp) malloc(sizeof(nl_t))) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not malloc!\n");
- X exit(1);
- X }
- X np->nl_net = strsave(nbuf);
- X np->nl_netlen = strlen(nbuf);
- X np->nl_file = strsave(fbuf);
- X np->nl_fp = NULL;
- X np->nl_next = ntop;
- X ntop = np;
- X cnt++;
- X }
- X (void) fclose(fp);
- X
- X /*
- X * figure out how many open files we can have: Max (getdtablesize) minus:
- X * 1 for stderr (stdin & stdout closed) 1 for domain (output) file
- X * (argv[1])
- X */
- X
- X i = getdtablesize() - 2;
- X if (cnt > i) {
- X (void) fprintf(stderr, "hostcvt: can not have more than %d entries (you have %d)\n", i, cnt);
- X exit(1);
- X }
- X
- X for (np = ntop; np != NULL; np = np->nl_next) {
- X if ((np->nl_fp = fopen(np->nl_file, "w")) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not open %s for write\n", np->nl_file);
- X continue;
- X }
- X if (soa != NULL) {
- X (void) fputs(soa, np->nl_fp);
- X }
- X }
- X}
- X
- Xrdsoa(file)
- Xchar *file;
- X{
- X int read(), open(), fstat();
- X register int fd, rv;
- X struct stat stb;
- X
- X if ((fd = open(file, O_RDONLY, 0)) == -1) {
- X soa = NULL;
- X (void) fprintf(stderr, "hostcvt: could not open SOA file, skipping\n");
- X return;
- X }
- X
- X if (fstat(fd, &stb) == -1) {
- X (void) fprintf(stderr, "hostcvt: could not fstat %s (%d)\n", ERR);
- X exit(1);
- X }
- X
- X if ((soa = malloc((unsigned) stb.st_size)) == NULL) {
- X (void) fprintf(stderr, "hostcvt: could not malloc enough for SOA file (%s)\n", file);
- X exit(1);
- X }
- X
- X if ((rv = read(fd, soa, (int) stb.st_size)) != stb.st_size) {
- X (void) fprintf(stderr, "hostcvt: asked to read %d, got %d", (int) stb.st_size, rv);
- X if (rv == -1){
- X (void) fprintf(stderr, " - %s (%d)", ERR);
- X }
- X
- X (void) fprintf(stderr, "\n");
- X exit(1);
- X }
- X
- X (void) close(fd);
- X}
- X
- Xchar *
- Xstrsave(str)
- Xregister char *str;
- X{
- X char *malloc(), *strcpy();
- X register char *cp;
- X
- X if (str == NULL)
- X return (NULL);
- X
- X if ((cp = malloc((unsigned) (strlen(str) + 1))) != NULL)
- X (void) strcpy(cp, str);
- X
- X return (cp);
- X}
- END_OF_main.c
- if test 10143 -ne `wc -c <main.c`; then
- echo shar: \"main.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f nextserial.8 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"nextserial.8\"
- else
- echo shar: Extracting \"nextserial.8\" \(1311 characters\)
- sed "s/^X//" >nextserial.8 <<'END_OF_nextserial.8'
- X.\"
- X.\" $Id: nextserial.8,v 1.1 90/10/03 23:34:03 rogers Release $
- X.\"
- X.TH NEXTSERIAL 8 "10-3-90"
- X.SH NAME
- Xnextserial - Increment the BIND SOA Serial number in a file
- X.SH SYNOPSIS
- X.B nextserial
- X.I soafile
- X.SH DESCRIPTION
- X.LP
- X.I nextserial
- Xreads the
- X.I soafile
- Xfile for a line containing the (regular expression) pattern "Serial".
- XThis line is assumed to be the line containing the SOA Serial
- Xnumber. The number is read from the line and incremented. The
- Xline is then written with the new serial number. All other lines
- Xare put through unchanged.
- X.SH "EXAMPLE"
- X.LP
- XGiven the
- X.I soafile
- Xfor our domain (wr.tek.com):
- X.RS
- X.nf
- X
- X@ IN SOA wrgate.wr.tek.com. wrap.wrgate.wr.tek.com. (
- X 1 ; Serial
- X 3600 ; Refresh
- X 300 ; Retry
- X 3600000 ; Expire
- X 14400 ) ; Minimum
- X IN NS wrgate.wr.tek.com.
- X.fi
- X.RE
- X.LP
- XRunning
- X.I "nextserial soafile"
- Xwould result in the
- X.I soafile
- Xlooking like:
- X.RS
- X.nf
- X
- X@ IN SOA wrgate.wr.tek.com. wrap.wrgate.wr.tek.com. (
- X 2 ; Serial
- X 3600 ; Refresh
- X 300 ; Retry
- X 3600000 ; Expire
- X 14400 ) ; Minimum
- X IN NS wrgate.wr.tek.com.
- X.fi
- X.RE
- X.SH "SEE ALSO"
- Xhostcvt(8)
- X.SH BUGS
- XSince the program uses regex() to find the line with "Serial" on it,
- Xthe
- X.I soafile
- Xshould have no other lines with that string on it.
- X.SH AUTHOR
- XRoger S. Southwick
- X.br
- Xrogers@dadla.wr.tek.com
- END_OF_nextserial.8
- if test 1311 -ne `wc -c <nextserial.8`; then
- echo shar: \"nextserial.8\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f nextserial.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"nextserial.c\"
- else
- echo shar: Extracting \"nextserial.c\" \(2026 characters\)
- sed "s/^X//" >nextserial.c <<'END_OF_nextserial.c'
- X#include <stdio.h>
- X
- X#ifndef lint
- Xstatic char *RCSid = "$Id: nextserial.c,v 1.1 90/10/03 22:56:42 rogers Release $";
- X#endif
- X
- X#define PAT "Serial"
- X
- Xextern int errno;
- Xextern char *sys_errlist[];
- X#define ERR sys_errlist[errno]
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *fopen();
- X char *re_comp(), *fgets(), *index(), *mktemp();
- X register char *cp;
- X register FILE *infp, *outfp;
- X register char *tmpname;
- X char buf[BUFSIZ];
- X int serial;
- X
- X (void)umask(022);
- X
- X if(argc != 2){
- X (void)fprintf(stderr, "usage: nextserial soafile\n");
- X exit(1);
- X }
- X
- X if((cp = re_comp(PAT)) != NULL){
- X (void)fprintf(stderr, "nextserial: %s\n", cp);
- X exit(1);
- X }
- X
- X tmpname = mktemp(".nxtXXXXXX");
- X (void)unlink(tmpname);
- X
- X if(rename(argv[1], tmpname) == -1){
- X (void)fprintf(stderr, "nextserial: could not rename(%s, %s) - %s (%d)\n", argv[1], tmpname, ERR);
- X exit(1);
- X }
- X
- X if((infp = fopen(tmpname, "r")) == NULL){
- X (void)fprintf(stderr, "nextserial: could not open %s for read\n", tmpname);
- X
- X if(rename(tmpname, argv[1]) == -1)
- X (void)fprintf(stderr, "EKK! could not put %s back to %s!\n", tmpname, argv[1]);
- X exit(1);
- X }
- X
- X if((outfp = fopen(argv[1], "w")) == NULL){
- X (void)fprintf(stderr, "nextserial: could not open %s for write\n", argv[1]);
- X
- X if(rename(tmpname, argv[1]) == -1)
- X (void)fprintf(stderr, "EKK! could not put %s back to %s!\n", tmpname, argv[1]);
- X exit(1);
- X }
- X
- X while(fgets(buf, BUFSIZ, infp) != NULL){
- X switch(re_exec(buf)){
- X case 0:
- X (void)fputs(buf, outfp);
- X break;
- X
- X case -1:
- X default:
- X (void)fprintf(stderr, "nextserial: regex internal error\n");
- X exit(1);
- X
- X case 1:
- X if((cp = index(buf, '\n')) != NULL)
- X *cp = '\0';
- X
- X if(sscanf(buf, "%d", &serial) != 1){
- X (void)fprintf(stderr, "nextserial: could not decode [%s]\n", buf);
- X exit(1);
- X }
- X
- X (void)fprintf(outfp, "\t\t\t\t%d\t; %s\n", ++serial, PAT);
- X break;
- X }
- X }
- X (void)fclose(outfp);
- X (void)fclose(infp);
- X (void)unlink(tmpname);
- X exit(0);
- X}
- END_OF_nextserial.c
- if test 2026 -ne `wc -c <nextserial.c`; then
- echo shar: \"nextserial.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 1 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-